package win.larryzeal.websocketdemo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistration;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import win.larryzeal.websocketdemo.web.WsHandler;

import javax.websocket.ContainerProvider;

// TODO:这是SpringMVC的方式，需要被导入MVC配置中 -- 见MvcConfig.class的@Import
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

	//由于拦截器将http session attr存入了websocket session，所以可以让http请求与websocket信息互动--就是http获取websocket的内容，或反之。
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
		WebSocketHandlerRegistration registration = registry.addHandler(this.wsHandler(), "/ws");//可以注册多个
		registration.addInterceptors(new HttpSessionHandshakeInterceptor());//将HTTP session attributes传递到WebSocket session
		registration.setAllowedOrigins("*"); //Spring 4.1.5起，默认允许同源请求，也可以指定允许的源，或者*代表全部。

		WebSocketHandlerRegistration registration2 = registry.addHandler(this.wsHandler(), "/sockjs/ws");//可以注册多个
		registration2.addInterceptors(new HttpSessionHandshakeInterceptor());//将HTTP session attributes传递到WebSocket session
		registration2.setAllowedOrigins("*"); //Spring 4.1.5起，默认允许同源请求，也可以指定允许的源，或者*代表全部。
		registration2.withSockJS();//如果要启用SockJS的话
	}

	@Bean // 奇怪，为毛不@Controller？？？ TODO
	public WebSocketHandler wsHandler(){
		return new WsHandler();
	}


	// 配置WebSocket引擎。for Tomcat、WildFly、还有GlassFish
//	@Bean
	public ServletServerContainerFactoryBean createWebSocketContainer(){
//		ContainerProvider.getWebSocketContainer()
		ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
		container.setMaxTextMessageBufferSize(8192);
		container.setMaxBinaryMessageBufferSize(8192);
		return container;
	}

}

// Spring提供了一个WebSocketHandlerDecorator基类，可以用额外的行为来装饰一个WebSocketHandler。使用WebSocket Java-config或XML namespace时，默认就添加了日志和异常处理实现。
// ExceptionWebSocketHandlerDecorator会捕获任意WebSocketHandler method抛出的所有的未捕获的异常，还会关闭WebSocket session并使用status 1011 来表明一个服务器错误。